home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
editors
/
mntemacs.zoo
/
src
/
fns.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-02
|
34KB
|
1,381 lines
/* Random utility Lisp functions.
Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "config.h"
#ifdef LOAD_AVE_TYPE
#ifdef BSD
/* It appears param.h defines BSD and BSD4_3 in 4.3
and is not considerate enough to avoid bombing out
if they are already defined. */
#undef BSD
#ifdef BSD4_3
#undef BSD4_3
#define XBSD4_3 /* XBSD4_3 says BSD4_3 is supposed to be defined. */
#endif
#include <sys/param.h>
/* Now if BSD or BSD4_3 was defined and is no longer,
define it again. */
#ifndef BSD
#define BSD
#endif
#ifdef XBSD4_3
#ifndef BSD4_3
#define BSD4_3
#endif
#endif /* XBSD4_3 */
#endif /* BSD */
#ifndef VMS
#ifndef NLIST_STRUCT
#include <a.out.h>
#else /* NLIST_STRUCT */
#include <nlist.h>
#endif /* NLIST_STRUCT */
#endif /* not VMS */
#endif /* LOAD_AVE_TYPE */
/* Note on some machines this defines `vector' as a typedef,
so make sure we don't use that name in this file. */
#undef vector
#define vector *****
#ifdef NULL
#undef NULL
#endif
#include "lisp.h"
#include "commands.h"
#ifdef lint
#include "buffer.h"
#endif /* lint */
Lisp_Object Qstring_lessp;
DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
"Return the argument unchanged.")
(arg)
Lisp_Object arg;
{
return arg;
}
DEFUN ("random", Frandom, Srandom, 0, 1, 0,
"Return a pseudo-random number.\n\
On most systems all integers representable in Lisp are equally likely.\n\
This is 24 bits' worth.\n\
On some systems, absolute value of result never exceeds 2 to the 14.\n\
If optional argument is supplied as t,\n\
the random number seed is set based on the current time and pid.")
(arg)
Lisp_Object arg;
{
extern long random ();
extern srandom ();
extern long time ();
if (EQ (arg, Qt))
srandom (getpid () + time (0));
return make_number ((int) random ());
}
/* Random data-structure functions */
DEFUN ("length", Flength, Slength, 1, 1, 0,
"Return the length of vector, list or string SEQUENCE.")
(obj)
register Lisp_Object obj;
{
register Lisp_Object tail, val;
register int i;
retry:
if (XTYPE (obj) == Lisp_Vector || XTYPE (obj) == Lisp_String)
return Farray_length (obj);
else if (CONSP (obj))
{
for (i = 0, tail = obj; !NULL(tail); i++)
{
QUIT;
tail = Fcdr (tail);
}
XFASTINT (val) = i;
return val;
}
else if (NULL(obj))
{
XFASTINT (val) = 0;
return val;
}
else
{
obj = wrong_type_argument (Qsequencep, obj);
goto retry;
}
}
DEFUN ("string-equal", Fstring_equal, Sstring_equal, 2, 2, 0,
"T if two strings have identical contents.\n\
Symbols are also allowed; their print names are used instead.")
(s1, s2)
register Lisp_Object s1, s2;
{
if (XTYPE (s1) == Lisp_Symbol)
XSETSTRING (s1, XSYMBOL (s1)->name), XSETTYPE (s1, Lisp_String);
if (XTYPE (s2) == Lisp_Symbol)
XSETSTRING (s2, XSYMBOL (s2)->name), XSETTYPE (s2, Lisp_String);
CHECK_STRING (s1, 0);
CHECK_STRING (s2, 1);
if (XSTRING (s1)->size != XSTRING (s2)->size ||
bcmp (XSTRING (s1)->data, XSTRING (s2)->data, XSTRING (s1)->size))
return Qnil;
return Qt;
}
DEFUN ("string-lessp", Fstring_lessp, Sstring_lessp, 2, 2, 0,
"T if first arg string is less than second in lexicographic order.\n\
Symbols are also allowed; their print names are used instead.")
(s1, s2)
register Lisp_Object s1, s2;
{
register int i;
register unsigned char *p1, *p2;
register int end;
if (XTYPE (s1) == Lisp_Symbol)
XSETSTRING (s1, XSYMBOL (s1)->name), XSETTYPE (s1, Lisp_String);
if (XTYPE (s2) == Lisp_Symbol)
XSETSTRING (s2, XSYMBOL (s2)->name), XSETTYPE (s2, Lisp_String);
CHECK_STRING (s1, 0);
CHECK_STRING (s2, 1);
p1 = XSTRING (s1)->data;
p2 = XSTRING (s2)->data;
end = XSTRING (s1)->size;
if (end > XSTRING (s2)->size)
end = XSTRING (s2)->size;
for (i = 0; i < end; i++)
{
if (p1[i] != p2[i])
return p1[i] < p2[i] ? Qt : Qnil;
}
return i < XSTRING (s2)->size ? Qt : Qnil;
}
static Lisp_Object concat ();
/* ARGSUSED */
Lisp_Object
concat2 (s1, s2)
Lisp_Object s1, s2;
{
#ifdef NO_ARG_ARRAY
Lisp_Object args[2];
args[0] = s1;
args[1] = s2;
return concat (2, args, Lisp_String, 0);
#else
return concat (2, &s1, Lisp_String, 0);
#endif /* NO_ARG_ARRAY */
}
DEFUN ("append", Fappend, Sappend, 0, MANY, 0,
"Concatenate arguments and make the result a list.\n\
The result is a list whose elements are the elements of all the arguments.\n\
Each argument may be a list, vector or string.")
(nargs, args)
int nargs;
Lisp_Object *args;
{
return concat (nargs, args, Lisp_Cons, 1);
}
DEFUN ("concat", Fconcat, Sconcat, 0, MANY, 0,
"Concatenate arguments and make the result a string.\n\
The result is a string whose elements are the elements of all the arguments.\n\
Each argument may be a string, a list of numbers, or a vector of numbers.")
(nargs, args)
int nargs;
Lisp_Object *args;
{
return concat (nargs, args, Lisp_String, 0);
}
DEFUN ("vconcat", Fvconcat, Svconcat, 0, MANY, 0,
"Concatenate arguments and make the result a vector.\n\
The result is a vector whose elements are the elements of all the arguments.\n\
Each argument may be a list, vector or string.")
(nargs, args)
int nargs;
Lisp_Object *args;
{
return concat (nargs, args, Lisp_Vector, 0);
}
DEFUN ("copy-sequence", Fcopy_sequence, Scopy_sequence, 1, 1, 0,
"Return a copy of a list, vector or string.")
(arg)
Lisp_Object arg;
{
if (NULL (arg)) return arg;
if (!CONSP (arg) && XTYPE (arg) != Lisp_Vector && XTYPE (arg) != Lisp_String)
arg = wrong_type_argument (Qsequencep, arg);
return concat (1, &arg, CONSP (arg) ? Lisp_Cons : XTYPE (arg), 0);
}
static Lisp_Object
concat (nargs, args, target_type, last_special)
int nargs;
Lisp_Object *args;
enum Lisp_Type target_type;
int last_special;
{
Lisp_Object val;
Lisp_Object len;
register Lisp_Object tail;
register Lisp_Object this;
int toindex;
register int leni;
register int argnum;
Lisp_Object last_tail;
Lisp_Object prev;
/* In append, the last arg isn't treated like the others */
if (last_special && nargs > 0)
{
nargs--;
last_tail = args[nargs];
}
else
last_tail = Qnil;
for (argnum = 0; argnum < nargs; argnum++)
{
this = args[argnum];
if (!(CONSP (this) || NULL (this)
|| XTYPE (this) == Lisp_Vector || XTYPE (this) == Lisp_String))
{
if (XTYPE (this) == Lisp_Int)
args[argnum] = Fint_to_string (this);
else
args[argnum] = wrong_type_argument (Qsequencep, this);
}
}
for (argnum = 0, leni = 0; argnum < nargs; argnum++)
{
this = args[argnum];
len = Flength (this);
leni += XFASTINT (len);
}
XFASTINT (len) = leni;
if (target_type == Lisp_Cons)
val = Fmake_list (len, Qnil);
else if (target_type == Lisp_Vector)
val = Fmake_vector (len, Qnil);
else
val = Fmake_string (len, len);
/* In append, if all but last arg are nil, return last arg */
if (target_type == Lisp_Cons && EQ (val, Qnil))
return last_tail;
if (CONSP (val))
tail = val, toindex = -1; /* -1 in toindex is flag we are making a list */
else
toindex = 0;
prev = Qnil;
for (argnum = 0; argnum < nargs; argnum++)
{
Lisp_Object thislen;
int thisleni;
register int thisindex = 0;
this = args[argnum];
if (!CONSP (this))
thislen = Flength (this), thisleni = XINT (thislen);